package utils

import (
	"fmt"
	"os"

	"github.com/libp2p/go-libp2p/core/crypto"
)

func GetListenAddrStrings(port int) []string {
	addrsTemplates := []string{
		"/ip4/0.0.0.0/tcp/%d",
		"/ip4/0.0.0.0/udp/%d/quic-v1",
		"/ip4/0.0.0.0/udp/%d/quic-v1/webtransport",
		"/ip4/0.0.0.0/udp/%d/webrtc-direct",
		"/ip6/::/tcp/%d",
		"/ip6/::/udp/%d/quic-v1",
		"/ip6/::/udp/%d/quic-v1/webtransport",
		"/ip6/::/udp/%d/webrtc-direct",
	}
	addrs := []string{}
	for _, addrTmpl := range addrsTemplates {
		addr := fmt.Sprintf(addrTmpl, port)
		addrs = append(addrs, addr)
	}
	return addrs
}

func LoadKey(path string) (crypto.PrivKey, error) {
	data, err := os.ReadFile(path)
	if err != nil {
		return nil, err
	}
	return crypto.UnmarshalPrivateKey(data)
}

func GenAndSaveKeyPairWithType(keyPath string, keyType int) (crypto.PrivKey, crypto.PubKey, error) {
	if keyType < 0 {
		keyType = crypto.Ed25519
	}
	priv, pub, err := crypto.GenerateKeyPair(keyType, 0)
	if err != nil {
		return nil, nil, err
	}
	err = SavePrivateKey(keyPath, priv)
	if err != nil {
		return nil, nil, err
	}
	return priv, pub, nil
}

func GenAndSaveKeyPair(keyPath string) (crypto.PrivKey, crypto.PubKey, error) {
	return GenAndSaveKeyPairWithType(keyPath, -1)
}

func SavePrivateKey(keyPath string, priv crypto.PrivKey) error {
	keyData, err := crypto.MarshalPrivateKey(priv)
	if err != nil {
		return err
	}
	err = os.WriteFile(keyPath, keyData, 0644)
	if err != nil {
		return err
	}
	return nil
}
